import { _decorator, Button, Component, director, Node, RichText, isValid, sys, Director } from 'cc';
import { L } from './L';
/**
 * 安全的事件管理器（带日志系统）
 * 功能：
 * 1. 自动管理事件生命周期
 * 2. 弱引用避免内存泄漏
 * 3. 详细的调试日志
 * 4. 事件分组管理
 */
export class EventAutoManager {
    private _events: {
        nodeRef: WeakRef<Node>;
        event: any;
        handler: Function;
        target?: any;
        group?: string; // 新增分组字段
    }[] = [];

    // ================= 核心方法 =================
    /**
     * 注册事件（自动清理无效引用）
     * @param node 目标节点
     * @param event 事件名称
     * @param handler 处理函数
     * @param target 调用上下文
     * @param group 事件分组（可选）
     */
    on(node: Node, event: any, handler: Function, target?: any, group?: string) {
        this._cleanupInvalidRefs();
        
        node.on(event, handler, target);
        this._events.push({
            nodeRef: new WeakRef(node),
            event,
            handler,
            target,
            group // 存储分组信息
        });

        L.debug('EventAutoManager', 
            `注册事件: ${event}\n` +
            `节点: ${node.name || node.uuid}\n` +
            `回调: ${handler.name || '匿名函数'}` +
            (target ? `\n上下文: ${target.constructor.name}` : '') +
            (group ? `\n分组: ${group}` : '')
        );
    }

    /**
     * 移除特定事件
     */
    off(node: Node, event: any) {
        this._cleanupInvalidRefs();

        let removedCount = 0;
        this._events = this._events.filter(entry => {
            const nodeFromRef = entry.nodeRef.deref();
            if (!nodeFromRef?.isValid) return false;
            
            if (nodeFromRef === node && entry.event === event) {
                nodeFromRef.off(event, entry.handler, entry.target);
                removedCount++;
                return false;
            }
            return true;
        });

        L.debug('EventAutoManager',
            `移除事件: ${event}\n` +
            `节点: ${node.name || node.uuid}\n` +
            `已移除监听器: ${removedCount}个`
        );
    }

    /**
     * 移除指定分组的所有事件
     * @param group 要移除的分组名称
     */
    offGroup(group: string) {
        this._cleanupInvalidRefs();

        let removedCount = 0;
        this._events = this._events.filter(entry => {
            const nodeFromRef = entry.nodeRef.deref();
            if (!nodeFromRef?.isValid) return false;
            
            if (entry.group === group) {
                nodeFromRef.off(entry.event, entry.handler, entry.target);
                removedCount++;
                return false;
            }
            return true;
        });

        L.debug('EventAutoManager',
            `移除分组事件: ${group}\n` +
            `已移除监听器: ${removedCount}个`
        );
    }

    /**
     * 移除所有事件
     */
    offAll() {
        let totalRemoved = 0;
        this._events.forEach(entry => {
            const node = entry.nodeRef.deref();
            if (node?.isValid) {
                node.off(entry.event, entry.handler, entry.target);
                totalRemoved++;
            }
        });
        this._events = [];

        L.debug('EventAutoManager',
            `清理所有事件\n` +
            `共移除监听器: ${totalRemoved}个`
        );
    }

    // ================= 私有方法 =================
    /**
     * 清理无效引用（自动调用）
     */
    private _cleanupInvalidRefs() {
        const initialCount = this._events.length;
        this._events = this._events.filter(entry => {
            const node = entry.nodeRef.deref();
            return node?.isValid;
        });

        if (this._events.length < initialCount) {
            L.debug('EventAutoManager',
                `自动清理无效引用\n` +
                `已清理: ${initialCount - this._events.length}个`
            );
        }
    }

    // ================= 辅助方法 =================
    /**
     * 当前监听中的事件数量（调试用）
     */
    get listenerCount(): number {
        this._cleanupInvalidRefs();
        return this._events.length;
    }

    /**
     * 获取指定分组的事件数量
     * @param group 分组名称
     */
    getGroupListenerCount(group: string): number {
        this._cleanupInvalidRefs();
        return this._events.filter(entry => entry.group === group).length;
    }
}